﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MesGLApp.Tools
{
    public static class EntityTools
    {
        /// <summary>
        /// 深复制对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T DeepClone<T>(T obj)
        {
            if (obj == null)
                return default(T);

            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream memoryStream = new MemoryStream();

            formatter.Serialize(memoryStream, obj);
            memoryStream.Position = 0;

            T copy = (T)formatter.Deserialize(memoryStream);
            memoryStream.Close();

            return copy;
        }

        public static void CopyEntity<T1, T2>(T1 sour, ref T2 desc)
        {
            if (sour != null && desc != null)
            {
                Type sourT = sour.GetType();
                Type descT = desc.GetType();
                foreach (var sourItem in sourT.GetProperties())
                {
                    foreach (var descItem in descT.GetProperties())
                    {
                        if (descItem.Name.Equals(sourItem.Name) &&
                                descItem.PropertyType.Name.Equals(sourItem.PropertyType.Name))
                        {
                            descItem.SetValue(desc, sourItem.GetValue(sour));
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 判断两个类各属性的值是否一致
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sour"></param>
        /// <param name="desc"></param>
        /// <returns>返回True时，代表两个类各属性的值一样；反之，则返回False</returns>
        public static Boolean IsDiffForValue<T>(T sour, T desc)
        {
            Boolean isDiff = true;
            if (sour != null && desc != null)
            {
                Type tmpType = sour.GetType();
                foreach (var prop in tmpType.GetProperties())
                {
                    if (prop.GetValue(sour) == null && prop.GetValue(desc) != null)
                    {
                        isDiff = false;
                        break;
                    }
                    else if (prop.GetValue(sour) != null && prop.GetValue(desc) == null)
                    {
                        isDiff = false;
                        break;
                    }
                    else if (prop.GetValue(sour) == null && prop.GetValue(desc) == null)
                    {
                        isDiff = true;
                    }
                    else
                    {
                        Console.WriteLine(prop.GetValue(sour).ToString() + "-------" + prop.GetValue(desc).ToString());
                        if (Object.Equals(prop.GetValue(sour), prop.GetValue(desc)) == false)
                        {
                            isDiff = false;
                            break;
                        }
                    }
                }
            }
            return isDiff;
        }


        /// <summary>
        /// 比较两个同类的变量各属性值是否一致，不一致时产生比较结果返回，主要用于写日志
        /// </summary>
        /// <typeparam name="T">比较的类型</typeparam>
        /// <param name="sour">源变量</param>
        /// <param name="desc">目标变量</param>
        /// <returns></returns>
        public static string CompareForValue<T>(T sour, T desc)
        {
            string tmpStr = "";
            if (sour != null && desc != null)
            {
                Type tmpType = sour.GetType();
                foreach (var prop in tmpType.GetProperties())
                {
                    if (Object.Equals(prop.GetValue(sour), prop.GetValue(desc)) == false)
                    {
                        tmpStr = tmpStr + "{" + prop.Name + "|" + prop.GetValue(sour).ToString() + "|" + prop.GetValue(desc) + "},";
                    }
                }
                if (tmpStr.Trim().Length > 0)
                {
                    tmpStr = tmpStr.Substring(0, tmpStr.Trim().Length - 1);
                }
            }
            return tmpStr;
        }


        public static string GetPropNameAndValue<T>(T obj)
        {
            string resStr = "";
            if (obj != null)
            {
                Type type = obj.GetType();
                foreach (var prop in type.GetProperties())
                {
                    if (prop.GetValue(obj) != null)
                    {
                        resStr = resStr + prop.Name + ":" + prop.GetValue(obj).ToString() + "|";
                    }
                    else
                    {
                        resStr = resStr + prop.Name + ":null|";
                    }
                }
                if (resStr.Trim().Length > 0)
                {
                    resStr = resStr.Substring(0, resStr.Length - 1);
                }
            }
            return resStr;
        }
    }
}
